package myStruct

type Element struct {
	Val  interface{}
	next *Element
	prev *Element
}

func (e *Element) Next() *Element {
	return e.next
}

func (e *Element) Prev() *Element {
	return e.prev
}

type List struct {
	start *Element
	end   *Element
	size  int
}

func NewList() *List { return &List{} }
func (l *List) Init() {
	l.start, l.end = nil, nil
	l.size = 0
}
func (l List) Len() int        { return l.size }
func (l List) Front() *Element { return l.start }
func (l List) Back() *Element  { return l.end }
func (l *List) PushFront(v interface{}) *Element {
	e := Element{
		Val:  v,
		next: l.start,
	}

	if l.start != nil {
		l.start.prev = &e
	} else {
		l.end = &e
	}
	l.start = &e

	l.size++

	return l.start
}
func (l *List) PushBack(v interface{}) *Element {
	e := Element{
		Val:  v,
		prev: l.end,
	}

	if l.end != nil {
		l.end.next = &e
	} else {
		l.start = &e
	}

	l.end = &e
	l.size++

	return l.end
}
func (l *List) PopFront() *Element {
	if l.start == nil {
		return nil
	}

	e := l.start
	if e.next == nil {
		l.end = e.next
	}
	l.start = e.next
	l.size--
	return e
}
func (l *List) PopBack() *Element {
	if l.end == nil {
		return nil
	}

	e := l.end
	if e.prev == nil {
		l.start = e.prev
	}
	l.end = e.prev
	l.size--
	return e
}
